-
Notifications
You must be signed in to change notification settings - Fork 1.5k
C++ Interop: API importing and semantics #6358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Conversation
This includes high level design ideas and the basics of importing C++ APIs and function calling. Leaving plenty of TODOs to make it easier to fill in more details in followups.
jonmeow
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's an important distinction of implementation versus design... Where you talk about a specific implementation requirement using Clang, I think that's a toolchain design detail. That'd suggest to me that the details are more appropriate for toolchain/docs (implementation) than docs/design (language design).
That is, for our implementation, we have chosen to use Clang and we're making implementation trade-offs based on that. However, if someone chose to build their own Carbon compiler, they should have freedom to choose a C++ compiler that suited them so long as it fit the higher-level language needs.
Also for language design, I think we typically want proposals first, then language design changes (or, put the language design change in with the proposal). But I'm just going to swap myself out for review with zygoloid since that's more of a leads choice, and he's also familiar with what's being done here.
jonmeow
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just highlighting a few things from a read-through, but trying not to get into many details because of the mix of design and implementation here.
Thanks Jon! |
Waiting for @zygoloid review. |
zygoloid
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems reasonable, but I think there are details here that haven't been through the proposal process, so it'd make sense to add a little pro forma /proposals/p6358.md here and treat this as a proposal so we can give it the weight of being an approved design change.
| The design of Carbon's C++ interoperability is governed by its foundational | ||
| goal: [to be a successor language](/README.md), not merely a language with a | ||
| foreign function interface (FFI). This mandate dictates a design that moves | ||
| beyond the C-style FFI adopted by most modern languages and instead provides | ||
| "seamless, bidirectional interoperability". The objective is to support deep | ||
| integration with existing C++ code, encompassing its most complex features, | ||
| "from inheritance to templates". | ||
|
|
||
| This goal has profound implications for the Carbon compiler and language | ||
| semantics. It requires that C++ is not treated as a "foreign" entity. Instead, | ||
| Carbon's semantic model must be _co-designed_ to understand, map, and interact | ||
| with C++'s semantic constructs—including templates, class hierarchies, and | ||
| complex overload resolution—with high fidelity. The interoperability layer must, | ||
| therefore, operate at the semantic analysis level, not just at the linking (ABI) | ||
| level. This document specifies the design of this semantic contract. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would drop all the double-quotes here. While these quotes are pulled from the main README, I don't think that's worth calling out, especially since we're quoting ourselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| compiler. Any operation involving a type that is designated as a C++ interop | ||
| type could invoke the specialized interoperability logic, such as C++ overload | ||
| resolution or operator overload resolution that involves both Carbon and C++ | ||
| operator overloads.. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| operator overloads.. | |
| operator overloads. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| 4. A Carbon struct or class containing a C++ interop type as a member (for | ||
| example, `MyCarbonStruct { x: Cpp.Widget }`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want this fourth case? It sounds expensive to check whether Carbon classes are compounded from C++ types in general, and I'm not sure we know yet what Carbon struct types would map into in C++, but I don't think it's likely that there'll be C++ operations defined for either case.
Maybe we can narrow this down to just Carbon class types that extend a C++ type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| This "pervasive" model of C++-awareness is a fundamental design choice. The C++ | ||
| semantics are not confined to a specific `unsafe` or `extern "C++"` block; they | ||
| affect any Carbon type that composes them. For example, when the Carbon compiler | ||
| instantiates a _Carbon_ generic type like `MyCarbonVector(Cpp.Widget)`, its type | ||
| system must be aware that the `Cpp.Widget` parameter carries C++-specific rules. | ||
| This mandates that Carbon's own generic system, struct layout logic, overload | ||
| resolution and operator lookup must query the type system for the presence of a | ||
| C++ interop type. If present, Carbon must consider C++ rules when operating over | ||
| C++ interop types. This design prioritizes the goal of a "seamless" and | ||
| "intuitive" user experience. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, I'd drop the double-quotes here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| This syntax is used for both C-style standard libraries and C++ headers: | ||
|
|
||
| - **C Standard Library:** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| This syntax is used for both C-style standard libraries and C++ headers: | |
| - **C Standard Library:** | |
| This syntax is used for both standard library headers and user-defined headers: | |
| - **Standard Library:** |
I think we should try to avoid mentioning C here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I've created a proposal, which assumes the proposal #6254 is accepted. |
This proposal defines the concrete technical mechanisms for C++
interoperability. It builds on the high-level directional agreement of #6254
("Calling C++ Functions") by specifying the precise syntax and semantics for
importing C++ APIs. This includes the
import Cpp library "..."and implicitlyimporting C++ built-in entities, and the establishment of the
Cpppackage asthe dedicated namespace for all imported entities.
This PR also includes high level language C++ Interop design and the basics of importing C++ APIs and function calling.
Leaving plenty of TODOs to make it easier to fill in more details in followups.
Part of #4666.